001 /**
002 * Created by IntelliJ IDEA.
003 * User: Wei Wang
004 * Date: Mar 2, 2003
005 * Time: 9:05:11 PM
006 */
007
008 package EVolve.visualization;
009
010 import javax.swing.*;
011 import java.awt.*;
012 import java.awt.event.MouseAdapter;
013 import java.awt.event.MouseEvent;
014 import java.awt.event.MouseMotionAdapter;
015 import java.awt.image.BufferedImage;
016 import java.awt.geom.AffineTransform;
017 import java.awt.geom.Point2D;
018 import java.awt.geom.Rectangle2D;
019 import java.util.ArrayList;
020
021 public class AxesPanel extends JPanel{
022 public final static int Axis_Enabled = 0x00001;
023 public final static int Scale_Image = 0x00010;
024 public final static int Flip_Image = 0x00100;
025 public final static int Pointer_Enabled = 0x01000;
026 public final static int Box_Enabled = 0x10000;
027 public final static int Null = 0x0;
028
029 private int flag;
030 private String xName=" ", yName=" ";
031 private Point origin, imageAdjustment, pointerPosition;
032 private Point boxStart, boxEnd;
033 private Point2D.Double mousePos;
034 private int zoomingWidth, zoomingHeight, shapeSize;
035 private BufferedImage image;
036 private JScrollPane parent = null;
037 private ArrayList phases;
038
039 public AxesPanel(int flag) {
040 this.flag = flag;
041 origin = new Point(0,0);
042 imageAdjustment = new Point(0,0);
043 pointerPosition = new Point(0,0);
044 boxStart = new Point(0,0);
045 boxEnd = new Point(0,0);
046 mousePos = new Point2D.Double(0,0);
047 zoomingWidth = zoomingHeight = 20;
048 shapeSize = 1;
049 if ((flag & 0x000f) == Axis_Enabled) {
050 origin.setLocation(20,20);
051 imageAdjustment.x = 60;
052 imageAdjustment.y = 60;
053 }
054 addMouseListener(new MouseAdapter() {
055 public void mousePressed(MouseEvent e) {
056 if (e.getButton() == MouseEvent.BUTTON1) {
057 mPressed(e.getX(), e.getY());
058 }
059 }
060 });
061
062 addMouseListener(new MouseAdapter() {
063 public void mouseReleased(MouseEvent e) {
064 if (e.getButton() == MouseEvent.BUTTON1) {
065 mReleased();
066 }
067 }
068 });
069
070 addMouseMotionListener(new MouseMotionAdapter() {
071 public void mouseDragged(MouseEvent e) {
072 mDragged(e.getX(), e.getY());
073 }
074 });
075 }
076
077 private void drawAxis(Graphics2D g2) {
078
079 if ((flag & 0x000f)==Axis_Enabled) {//axis is enabled
080 int w = getWidth(), h = getHeight();
081 g2.setColor(Color.black);
082 g2.drawLine(origin.x, h - origin.y, w - origin.x, h - origin.x);
083 g2.drawLine(w - origin.x, h - origin.y, w - 30, h - 15);
084 g2.drawLine(w - origin.x, h - origin.y, w - 30, h - 25);
085 g2.drawLine(origin.x, h - origin.y, origin.x, origin.y);
086 g2.drawLine(origin.x, origin.y, 15, 30);
087 g2.drawLine(origin.x, origin.y, 25, 30);
088
089
090 Font font = new Font("Arial", Font.PLAIN, 12);
091 g2.setFont(font);
092 g2.drawString(xName, w - g2.getFontMetrics().stringWidth(xName) - 40, h - 5);
093 g2.rotate(-Math.PI / 2.0);
094 g2.drawString(yName, -40 - g2.getFontMetrics().stringWidth(yName), 15);
095 g2.rotate(Math.PI / 2.0);
096 }
097 }
098
099 private void drawImage(Graphics2D g2) {
100 int w = getWidth(), h = getHeight(), flip = 1;
101 AffineTransform tf = g2.getTransform();
102
103 if ((flag&0x0f00)==Flip_Image) {
104 flip = -1;
105 g2.translate(origin.x+1, h - origin.y);
106 }
107
108 if ((flag&0x00f0)==Scale_Image) {
109 g2.scale((double)(w - imageAdjustment.x) / (double)(image.getWidth()),
110 (double)flip * (double)(h - imageAdjustment.y) / (double)(image.getHeight()));
111 g2.drawImage(image, 0, 0, null);
112 } else {
113 if ((flag&0x0000f) == Axis_Enabled) {
114 g2.scale(1,flip);
115 }
116 g2.drawImage(image, 0, 0, null);
117 }
118 g2.setTransform(tf);
119 }
120
121 private void drawBox(Graphics2D g2) {
122 g2.setColor(Color.blue);
123 int x1 = (boxStart.x < boxEnd.x) ? boxStart.x : boxEnd.x;
124 int x2 = (boxStart.x > boxEnd.x) ? boxStart.x : boxEnd.x;
125 int y1 = (boxStart.y < boxEnd.y) ? boxStart.y : boxEnd.y;
126 int y2 = (boxStart.y > boxEnd.y) ? boxStart.y : boxEnd.y;
127 g2.drawRect(x1, y1, x2 - x1, y2 - y1);
128 }
129
130 private void drawPhases(Graphics2D g2) {
131 double xFactor = 1;
132 int w = getWidth(), h = getHeight();
133
134 if (phases == null) return;
135
136 if ((flag&0x00f0)==Scale_Image) {
137 xFactor = (double)(w - imageAdjustment.x) / (double)(image.getWidth());
138 }
139
140 g2.setColor(Color.black);
141 for (int i=0; i<phases.size(); i++) {
142 int phaseEnd = ((Integer)phases.get(i)).intValue();
143
144 if (phaseEnd <= 0) continue;
145
146 g2.drawString(String.valueOf(phaseEnd),(int)(phaseEnd*xFactor)+origin.x,10);
147 g2.drawLine((int)(phaseEnd*xFactor)+origin.x, h-origin.y, (int)(phaseEnd*xFactor)+origin.x, origin.y);
148 }
149
150 }
151
152 private void drawPointer(Graphics2D g2) {
153 if ((flag&0xf000)==Pointer_Enabled) {
154 int x = pointerPosition.x, y = pointerPosition.y;
155 g2.setColor(Color.black);
156 g2.drawLine(x,y,x+20,y+20);
157 g2.drawLine(x,y,x+10,y+5);
158 g2.drawLine(x,y,x+5,y+10);
159 }
160 }
161
162 private void setPreferredPanelSize() {
163 if (parent == null) return;
164
165 if ((flag&0x000f0) != Scale_Image) {
166 setPreferredSize(new java.awt.Dimension(image.getWidth()+imageAdjustment.x,image.getHeight()+imageAdjustment.y));
167 } else {
168 setPreferredSize(new java.awt.Dimension(parent.getWidth()-14, parent.getHeight()-14));
169 }
170 revalidate();
171 }
172
173 public void paintComponent(Graphics g) {
174 super.paintComponent(g);
175
176 Graphics2D g2 = (Graphics2D)g;
177
178 int w = getWidth();
179 int h = getHeight();
180
181 g2.setColor(Color.white);
182 g2.fillRect(0, 0, w, h);
183
184 drawAxis(g2);
185
186 if (image != null) {
187 setPreferredPanelSize();
188 drawImage(g2);
189 drawBox(g2);
190 drawPhases(g2);
191 }
192 drawPointer(g2);
193
194 }
195
196 protected void mPressed(int x, int y) {
197 if (image != null) {
198 boxStart.x = x;
199 boxStart.y = y;
200 boxEnd.x = x;
201 boxEnd.y = y;
202 flag = flag | Box_Enabled;
203 repaint();
204 }
205 }
206
207 protected void mReleased() {
208 if (image != null) {
209 flag = flag & 0x0ffff;
210 }
211 }
212
213 protected void mDragged(int x, int y) {
214 if ((image != null)&&((flag &0xf0000) == Box_Enabled)) {
215 boxEnd.x = x;
216 boxEnd.y = y;
217 repaint();
218 }
219 }
220
221 public void setName(String xName, String yName) {
222 this.xName = xName;
223 this.yName = yName;
224 }
225
226 public void setImage(BufferedImage image) {
227 this.image = image;
228
229 boxStart.x = 0;
230 boxStart.y = 0;
231 boxEnd.x = 0;
232 boxEnd.y = 0;
233 flag = flag & 0x0ffff;
234 }
235
236 public int getImageX(int x) {
237 if (image == null) return -1;
238
239 if ((flag & 0x000f0) == Scale_Image)
240 return (int)((float)(x-origin.x)*((float)image.getWidth()/(float)(getWidth()-imageAdjustment.x)));
241 else
242 return x - origin.x;
243 }
244
245 public int getImageY(int y) {
246 if (image == null) return -1;
247
248 if ((flag & 0x000f0) == Scale_Image) {
249 if ((flag & 0x00f00) == Flip_Image)
250 return (int)((float)(getHeight()-origin.y-y)*((float)image.getHeight()/(float)(getHeight()-imageAdjustment.y)));
251 else
252 return (int)((float)(y-origin.y)*((float)image.getHeight()/(float)(getHeight()-imageAdjustment.y)));
253 }
254 else {
255 if ((flag & 0x00f00) == Flip_Image)
256 return getHeight()-origin.y-y;
257 else
258 return y - origin.y;
259 }
260 }
261
262 public int getStartX() {
263 int x = (boxStart.x < boxEnd.x) ? boxStart.x : boxEnd.x;
264 return getImageX(x);
265 }
266
267 public int getEndX() {
268 int x = (boxStart.x > boxEnd.x) ? boxStart.x : boxEnd.x;
269 return getImageX(x);
270 }
271
272 public int getStartY() {
273 int y = (boxStart.y < boxEnd.y) ? boxStart.y : boxEnd.y;
274 return getImageY(y);
275 }
276
277 public int getEndY() {
278 int y = (boxStart.y > boxEnd.y) ? boxStart.y : boxEnd.y;
279 return getImageY(y);
280 }
281
282 public void setPointerPosition(int x, int y) {
283 pointerPosition.x = x;
284 pointerPosition.y = y;
285 }
286
287 public void enablePointer(boolean draw) {
288 if (draw)
289 flag = flag | Pointer_Enabled;
290 else
291 flag = flag & (~Pointer_Enabled);
292 }
293
294 private Rectangle2D.Double calcZoomingArea(int x, int y) {
295 int w = image.getWidth(), h = image.getHeight();
296
297 double x1=x,y1=y,w1,h1;
298
299 x1 = x1 - (double)zoomingWidth*shapeSize/2;
300 y1 = y1 - (double)zoomingHeight*shapeSize/2;
301
302 w1 = zoomingWidth*shapeSize;
303 h1 = zoomingHeight*shapeSize;
304
305 mousePos.setLocation(shapeSize*zoomingWidth/2,shapeSize*zoomingHeight/2);
306 if (x1 < 0) {
307 mousePos.x+=x1;
308 w1 = w1+x1;
309 x1 = 0;
310 }
311 if (x1 + w1 > w) {
312 w1 = w - x1;
313 }
314
315 if (y1 < 0) {
316 mousePos.y+=y1;
317 h1 = h1+y1;
318 y1 = 0;
319 }
320 if (y1 + h1 > h) {
321 h1 = h - y1;
322 }
323
324 Rectangle2D.Double ret = new Rectangle2D.Double();
325 ret.x = x1;
326 ret.y = y1;
327 ret.width = w1;
328 ret.height = h1;
329 return ret;
330 }
331
332 public BufferedImage getSubImage(int x, int y) {
333 int w = image.getWidth(), h = image.getHeight();
334 Rectangle2D.Double zooming = calcZoomingArea(x,y);
335
336 if ((image == null)||(zooming.x>w)||(zooming.y>h))
337 return null;
338
339 if ((zooming.width<=0) || (zooming.height<=0)) return null;
340
341 return image.getSubimage((int)zooming.x,(int)zooming.y,(int)zooming.width,(int)zooming.height);
342 }
343
344 public void drawZoomingArea(int x, int y) {
345 double coX = 1, coY = 1;
346
347 if ((flag & 0x00f0) == Scale_Image) {
348 coX = (double)(getWidth() - imageAdjustment.x)/(double)image.getWidth();
349 coY = (double)(getHeight() - imageAdjustment.y)/(double)image.getHeight();
350 }
351 int deltaX = (int)(coX*zoomingWidth*shapeSize/2);
352 int deltaY = (int)(coY*zoomingHeight*shapeSize/2);
353
354 boxStart.x = x - deltaX;
355 boxStart.y = y - deltaY;
356 boxEnd.x = x + deltaX;
357 boxEnd.y = y + deltaY;
358 flag = flag | Box_Enabled;
359 repaint();
360 flag = flag & (~Box_Enabled);
361 }
362
363 public void setShapeSize(int shapeSize) {
364 this.shapeSize = shapeSize;
365 }
366
367 public void setZoomingSize(int w, int h) {
368 zoomingWidth = w;
369 zoomingHeight = h;
370 }
371
372 public Point2D.Double getMouseMovement() {
373 return mousePos;
374 }
375
376 public void scaleImage(boolean scaled) {
377 if (scaled)
378 flag = flag | Scale_Image;
379 else
380 flag = flag & (~Scale_Image);
381 }
382
383 public void setParent(JScrollPane parent) {
384 this.parent = parent;
385 }
386
387 public void setPanelFlag(int flag) {
388 this.flag = flag;
389 if ((flag & 0x000f) != Axis_Enabled) {
390 origin.setLocation(0,0);
391 imageAdjustment.x = 0;
392 imageAdjustment.y = 0;
393 }
394 }
395
396 public Point getOrigin() {
397 return origin;
398 }
399
400 public void setPhases(ArrayList phases) {
401 this.phases = phases;
402 }
403
404 public Object clone() {
405 AxesPanel o = new AxesPanel(flag);
406
407 o.xName = xName;
408 o.yName = yName;
409 o.zoomingWidth = zoomingWidth;
410 o.zoomingHeight = zoomingHeight;
411 o.shapeSize = shapeSize;
412 return o;
413 }
414 }